home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / _threading_local.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  6KB  |  248 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. """Thread-local objects
  5.  
  6. (Note that this module provides a Python version of thread
  7.  threading.local class.  Depending on the version of Python you're
  8.  using, there may be a faster one available.  You should always import
  9.  the local class from threading.)
  10.  
  11. Thread-local objects support the management of thread-local data.
  12. If you have data that you want to be local to a thread, simply create
  13. a thread-local object and use its attributes:
  14.  
  15.   >>> mydata = local()
  16.   >>> mydata.number = 42
  17.   >>> mydata.number
  18.   42
  19.  
  20. You can also access the local-object's dictionary:
  21.  
  22.   >>> mydata.__dict__
  23.   {'number': 42}
  24.   >>> mydata.__dict__.setdefault('widgets', [])
  25.   []
  26.   >>> mydata.widgets
  27.   []
  28.  
  29. What's important about thread-local objects is that their data are
  30. local to a thread. If we access the data in a different thread:
  31.  
  32.   >>> log = []
  33.   >>> def f():
  34.   ...     items = mydata.__dict__.items()
  35.   ...     items.sort()
  36.   ...     log.append(items)
  37.   ...     mydata.number = 11
  38.   ...     log.append(mydata.number)
  39.  
  40.   >>> import threading
  41.   >>> thread = threading.Thread(target=f)
  42.   >>> thread.start()
  43.   >>> thread.join()
  44.   >>> log
  45.   [[], 11]
  46.  
  47. we get different data.  Furthermore, changes made in the other thread
  48. don't affect data seen in this thread:
  49.  
  50.   >>> mydata.number
  51.   42
  52.  
  53. Of course, values you get from a local object, including a __dict__
  54. attribute, are for whatever thread was current at the time the
  55. attribute was read.  For that reason, you generally don't want to save
  56. these values across threads, as they apply only to the thread they
  57. came from.
  58.  
  59. You can create custom local objects by subclassing the local class:
  60.  
  61.   >>> class MyLocal(local):
  62.   ...     number = 2
  63.   ...     initialized = False
  64.   ...     def __init__(self, **kw):
  65.   ...         if self.initialized:
  66.   ...             raise SystemError('__init__ called too many times')
  67.   ...         self.initialized = True
  68.   ...         self.__dict__.update(kw)
  69.   ...     def squared(self):
  70.   ...         return self.number ** 2
  71.  
  72. This can be useful to support default values, methods and
  73. initialization.  Note that if you define an __init__ method, it will be
  74. called each time the local object is used in a separate thread.  This
  75. is necessary to initialize each thread's dictionary.
  76.  
  77. Now if we create a local object:
  78.  
  79.   >>> mydata = MyLocal(color='red')
  80.  
  81. Now we have a default number:
  82.  
  83.   >>> mydata.number
  84.   2
  85.  
  86. an initial color:
  87.  
  88.   >>> mydata.color
  89.   'red'
  90.   >>> del mydata.color
  91.  
  92. And a method that operates on the data:
  93.  
  94.   >>> mydata.squared()
  95.   4
  96.  
  97. As before, we can access the data in a separate thread:
  98.  
  99.   >>> log = []
  100.   >>> thread = threading.Thread(target=f)
  101.   >>> thread.start()
  102.   >>> thread.join()
  103.   >>> log
  104.   [[('color', 'red'), ('initialized', True)], 11]
  105.  
  106. without affecting this thread's data:
  107.  
  108.   >>> mydata.number
  109.   2
  110.   >>> mydata.color
  111.   Traceback (most recent call last):
  112.   ...
  113.   AttributeError: 'MyLocal' object has no attribute 'color'
  114.  
  115. Note that subclasses can define slots, but they are not thread
  116. local. They are shared across threads:
  117.  
  118.   >>> class MyLocal(local):
  119.   ...     __slots__ = 'number'
  120.  
  121.   >>> mydata = MyLocal()
  122.   >>> mydata.number = 42
  123.   >>> mydata.color = 'red'
  124.  
  125. So, the separate thread:
  126.  
  127.   >>> thread = threading.Thread(target=f)
  128.   >>> thread.start()
  129.   >>> thread.join()
  130.  
  131. affects what we see:
  132.  
  133.   >>> mydata.number
  134.   11
  135.  
  136. >>> del mydata
  137. """
  138.  
  139. class _localbase(object):
  140.     __slots__ = ('_local__key', '_local__args', '_local__lock')
  141.     
  142.     def __new__(cls, *args, **kw):
  143.         self = object.__new__(cls)
  144.         key = ('_local__key', 'thread.local.' + str(id(self)))
  145.         object.__setattr__(self, '_local__key', key)
  146.         object.__setattr__(self, '_local__args', (args, kw))
  147.         object.__setattr__(self, '_local__lock', RLock())
  148.         if (args or kw) and cls.__init__ is object.__init__:
  149.             raise TypeError('Initialization arguments are not supported')
  150.         
  151.         dict = object.__getattribute__(self, '__dict__')
  152.         currentThread().__dict__[key] = dict
  153.         return self
  154.  
  155.  
  156.  
  157. def _patch(self):
  158.     key = object.__getattribute__(self, '_local__key')
  159.     d = currentThread().__dict__.get(key)
  160.     if d is None:
  161.         d = { }
  162.         currentThread().__dict__[key] = d
  163.         object.__setattr__(self, '__dict__', d)
  164.         cls = type(self)
  165.         if cls.__init__ is not object.__init__:
  166.             (args, kw) = object.__getattribute__(self, '_local__args')
  167.             cls.__init__(self, *args, **kw)
  168.         
  169.     else:
  170.         object.__setattr__(self, '__dict__', d)
  171.  
  172.  
  173. class local(_localbase):
  174.     
  175.     def __getattribute__(self, name):
  176.         lock = object.__getattribute__(self, '_local__lock')
  177.         lock.acquire()
  178.         
  179.         try:
  180.             _patch(self)
  181.             return object.__getattribute__(self, name)
  182.         finally:
  183.             lock.release()
  184.  
  185.  
  186.     
  187.     def __setattr__(self, name, value):
  188.         lock = object.__getattribute__(self, '_local__lock')
  189.         lock.acquire()
  190.         
  191.         try:
  192.             _patch(self)
  193.             return object.__setattr__(self, name, value)
  194.         finally:
  195.             lock.release()
  196.  
  197.  
  198.     
  199.     def __delattr__(self, name):
  200.         lock = object.__getattribute__(self, '_local__lock')
  201.         lock.acquire()
  202.         
  203.         try:
  204.             _patch(self)
  205.             return object.__delattr__(self, name)
  206.         finally:
  207.             lock.release()
  208.  
  209.  
  210.     
  211.     def __del__():
  212.         threading_enumerate = enumerate
  213.         __getattribute__ = object.__getattribute__
  214.         
  215.         def __del__(self):
  216.             key = __getattribute__(self, '_local__key')
  217.             
  218.             try:
  219.                 threads = list(threading_enumerate())
  220.             except:
  221.                 return None
  222.  
  223.             for thread in threads:
  224.                 
  225.                 try:
  226.                     __dict__ = thread.__dict__
  227.                 except AttributeError:
  228.                     continue
  229.  
  230.                 if key in __dict__:
  231.                     
  232.                     try:
  233.                         del __dict__[key]
  234.                     except KeyError:
  235.                         pass
  236.                     except:
  237.                         None<EXCEPTION MATCH>KeyError
  238.                     
  239.  
  240.                 None<EXCEPTION MATCH>KeyError
  241.             
  242.  
  243.         return __del__
  244.  
  245.     __del__ = __del__()
  246.  
  247. from threading import currentThread, enumerate, RLock
  248.